package com.hbk.bo;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.io.FileUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class Application {
	
	private static Configuration freemarkerCfg = new Configuration();

	public static void main(String[] args) {
		buildModel1("producingMaterial.json");
	}
	
	private static void buildModel4(String str) {
		try {
			File file=new File("src/main/resources/antdesign/model4/json/"+str);
			String json=FileUtils.readFileToString(file, "UTF-8");
			Map<String,Object> config=json2Map(json);
			buildFile("antdesign/model4/index.ftl","src/pages"+config.get("url").toString()+"/index.js",config);
			buildFile("antdesign/model4/model.ftl","src/pages"+config.get("url").toString()+"/model.js",config);
			for(Map<String,Object> field:(List<Map<String,Object>>)config.get("fields")) {
				if(field.get("type").toString().equals("DataList")) {
					StringBuffer name = new StringBuffer(field.get("name").toString());
					name.setCharAt(0, Character.toUpperCase(name.charAt(0)));
					Map<String,Object> model=new HashMap<String,Object>();
					model.put("namespace",config.get("namespace").toString()+name.toString());
					buildFile("antdesign/model4/modelDataList.ftl","src/pages"+config.get("url").toString()+"/models/model"+name.toString()+".js",model);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void buildModel3(String str) {
		try {
			File file=new File("src/main/resources/antdesign/model3/json/"+str);
			String json=FileUtils.readFileToString(file, "UTF-8");
			Model1Config config=JSON.parseObject(json, new TypeReference<Model1Config>() {});
			buildFile("antdesign/model3/index.ftl","src/pages"+config.getUrl()+"/index.js",config);
			buildFile("antdesign/model3/model.ftl","src/pages"+config.getUrl()+"/models/model.js",config);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void buildModel2(String str) {
		try {
			File file=new File("src/main/resources/antdesign/model2/json/"+str);
			String json=FileUtils.readFileToString(file, "UTF-8");
			Model2Config config=JSON.parseObject(json, new TypeReference<Model2Config>() {});
			buildFile("antdesign/model2/index.ftl","src/pages"+config.getUrl()+"/index.js",config);
			buildFile("antdesign/model2/model.ftl","src/pages"+config.getUrl()+"/models/model.js",config);
			buildFile("antdesign/model2/modal.ftl","src/pages"+config.getUrl()+"/modal.js",config);
			String namespace=config.getNamespace();
			for(Field field:config.getModalProps().getFields()) {
				if(field.getType().equals("DataList")) {
					StringBuffer name = new StringBuffer(field.getName());
					name.setCharAt(0, Character.toUpperCase(name.charAt(0)));
					config.setNamespace(namespace+name.toString());
					buildFile("antdesign/model2/modelDataList.ftl","src/pages"+config.getUrl()+"/models/model"+name.toString()+".js",config);
				}
			}
			if(config.getModalProps().getAdd()) {
				StringBuffer name = new StringBuffer(config.getModalProps().getDataSource());
				name.setCharAt(0, Character.toUpperCase(name.charAt(0)));
				config.setNamespace(namespace+name.toString());
				buildFile("antdesign/model2/modelDataList.ftl","src/pages"+config.getUrl()+"/models/model"+name.toString()+".js",config);
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void buildModel1(String str) {
		try {
			File file=new File("src/main/resources/antdesign/model1/json/"+str);
			String json=FileUtils.readFileToString(file, "UTF-8");
			Model1Config config=JSON.parseObject(json, new TypeReference<Model1Config>() {});
			buildFile("antdesign/model1/index.ftl","src/pages"+config.getUrl()+"/index.js",config);
			buildFile("antdesign/model1/model.ftl","src/pages"+config.getUrl()+"/models/model.js",config);
			if(config.getModal()) {
				buildFile("antdesign/model1/modal.ftl","src/pages"+config.getUrl()+"/modal.js",config);
			}
			String namespace=config.getNamespace();
			for(Field field:config.getFields()) {
				if(field.getType().equals("DataList")) {
					StringBuffer name = new StringBuffer(field.getName());
					name.setCharAt(0, Character.toUpperCase(name.charAt(0)));
					config.setNamespace(namespace+name.toString());
					config.setApi(name.toString());
					buildFile("antdesign/model1/modelDataList.ftl","src/pages"+config.getUrl()+"/models/model"+name.toString()+".js",config);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void buildFile(String templateName, String fileName, Config root) throws Exception {
		try {
			System.err.println(fileName);
			freemarkerCfg.setClassForTemplateLoading(Application.class, "/");
			freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");
			Template template = freemarkerCfg.getTemplate(templateName);
			template.setEncoding("UTF-8");
			File htmlFile = new File(fileName);
			htmlFile.getParentFile().mkdirs();
			Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
			template.process(root, out);
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void buildFile(String templateName, String fileName, Map<String, Object> root) throws Exception {
		try {
			freemarkerCfg.setClassForTemplateLoading(Application.class, "/");
			freemarkerCfg.setEncoding(Locale.getDefault(), "UTF-8");
			Template template = freemarkerCfg.getTemplate(templateName);
			template.setEncoding("UTF-8");
			File htmlFile = new File(fileName);
			htmlFile.getParentFile().mkdirs();
			Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
			template.process(root, out);
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 将json字符串转为Map结构
	 * 如果json复杂，结果可能是map嵌套map
	 * @param jsonStr 入参，json格式字符串
	 * @return 返回一个map
	 */
	public static Map<String, Object> json2Map(String jsonStr) {
		Map<String, Object> map = new HashMap<>();
		if(jsonStr != null && !"".equals(jsonStr)){
			//最外层解析
			JSONObject json = JSONObject.parseObject(jsonStr);
			for (Object k : json.keySet()) {
				Object v = json.get(k);
				//如果内层还是数组的话，继续解析
				if (v instanceof JSONArray) {
					List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
					Iterator<Object> it = ((JSONArray) v).iterator();
					while (it.hasNext()) {
						JSONObject json2 = (JSONObject)it.next();
						list.add(json2Map(json2.toString()));
					}
					map.put(k.toString(), list);
				} else {
					map.put(k.toString(), v);
				}
			}
			return map;
		}else{
			return null;
		}
	}
}
